home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
graphics
/
tiff
/
tools
/
fax2tiff.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-10
|
9KB
|
284 lines
#ifndef lint
static char rcsid[] = "$Header: /usr/people/sam/tiff/tools/RCS/fax2tiff.c,v 1.15 92/02/10 19:04:17 sam Exp $";
#endif
/*
* Copyright (c) 1990, 1991, 1992 Sam Leffler
* Copyright (c) 1991, 1992 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
/*
* Convert a CCITT Group 3 FAX file to TIFF Group 3 format.
*/
#include <stdio.h>
#include <math.h> /* for atof declaration */
#include "tiffioP.h"
TIFF faxTIFF;
#define XSIZE 1728
u_char rowbuf[howmany(XSIZE,8)];
u_char refbuf[howmany(XSIZE,8)];
int verbose;
int stretch;
u_short badfaxrun;
u_long badfaxlines;
usage()
{
fprintf(stderr, "usage: fax2tiff [-2BLMW] [-R inres] [-14cfmpsv] [-o out.tif] faxfile ...\n");
exit(-1);
}
main(argc, argv)
int argc;
char *argv[];
{
FILE *in;
TIFF *out = NULL;
int compression = COMPRESSION_CCITTFAX3;
int fillorder = FILLORDER_LSB2MSB;
long group3options = GROUP3OPT_FILLBITS;
int photometric = PHOTOMETRIC_MINISWHITE;
int isClassF = 1;
int rows;
int c;
int pn, npages;
extern int optind;
extern char *optarg;
bzero(&faxTIFF, sizeof (faxTIFF));
TIFFSetField(&faxTIFF, TIFFTAG_IMAGEWIDTH, XSIZE);
TIFFSetField(&faxTIFF, TIFFTAG_SAMPLESPERPIXEL, 1);
TIFFSetField(&faxTIFF, TIFFTAG_BITSPERSAMPLE, 1);
TIFFSetField(&faxTIFF, TIFFTAG_FILLORDER, FILLORDER_LSB2MSB);
TIFFSetField(&faxTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(&faxTIFF, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
TIFFSetField(&faxTIFF, TIFFTAG_YRESOLUTION, 196.);
TIFFSetField(&faxTIFF, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
/* NB: this is normally setup when a directory is read */
faxTIFF.tif_scanlinesize = TIFFScanlineSize(&faxTIFF);
while ((c = getopt(argc, argv, "R:o:2BLMW14cflmpsvwz")) != -1)
switch (c) {
/* input-related options */
case '2': /* input is 2d-encoded */
TIFFSetField(&faxTIFF,
TIFFTAG_GROUP3OPTIONS, GROUP3OPT_2DENCODING);
break;
case 'B': /* input has 0 mean black */
TIFFSetField(&faxTIFF,
TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
break;
case 'L': /* input has lsb-to-msb fillorder */
TIFFSetField(&faxTIFF,
TIFFTAG_FILLORDER, FILLORDER_LSB2MSB);
break;
case 'M': /* input has msb-to-lsb fillorder */
TIFFSetField(&faxTIFF,
TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
break;
case 'R': /* input resolution */
TIFFSetField(&faxTIFF,
TIFFTAG_YRESOLUTION, atof(optarg));
break;
case 'W': /* input has 0 mean white */
TIFFSetField(&faxTIFF,
TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
break;
/* output-related options */
case '1': /* generate 1d-encoded output */
group3options &= ~GROUP3OPT_2DENCODING;
break;
case '4': /* generate g4-encoded output */
compression = COMPRESSION_CCITTFAX4;
break;
case 'c': /* generate "classic" g3 format */
isClassF = 0;
break;
case 'f': /* generate Class F format */
isClassF = 1;
break;
case 'm': /* output's fillorder is msb-to-lsb */
fillorder = FILLORDER_MSB2LSB;
break;
case 'o':
out = TIFFOpen(optarg, "w");
if (out == NULL)
exit(-2);
break;
case 'p': /* zero pad output scanline EOLs */
group3options &= ~GROUP3OPT_FILLBITS;
break;
case 's': /* stretch image by dup'ng scanlines */
stretch = 1;
break;
case 'w': /* undocumented -- for testing */
photometric = PHOTOMETRIC_MINISBLACK;
break;
case 'z': /* undocumented -- for testing */
compression = COMPRESSION_LZW;
break;
case 'v': /* -v for info */
verbose++;
break;
case '?':
usage();
/*NOTREACHED*/
}
if (out == NULL) {
out = TIFFOpen("fax.tif", "w");
if (out == NULL)
exit(-2);
}
faxTIFF.tif_fillorder = out->tif_fillorder; /* XXX */
npages = argc - optind;
if (npages < 1)
usage();
/* NB: this must be done after directory info is setup */
TIFFSetField(&faxTIFF, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX3);
for (pn = 0; optind < argc; pn++, optind++) {
in = fopen(argv[optind], "r");
if (in == NULL) {
fprintf(stderr,
"%s: %s: Can not open\n", argv[0], argv[optind]);
continue;
}
faxTIFF.tif_fd = fileno(in);
faxTIFF.tif_name = argv[optind];
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, XSIZE);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 1);
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
if (compression == COMPRESSION_CCITTFAX3) {
TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, group3options);
TIFFModeCCITTFax3(out, isClassF);
}
if (compression == COMPRESSION_CCITTFAX3 ||
compression == COMPRESSION_CCITTFAX4)
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, -1L);
else
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
(u_long) (8*1024)/TIFFScanlineSize(out));
TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
TIFFSetField(out, TIFFTAG_SOFTWARE, "fax2tiff");
TIFFSetField(out, TIFFTAG_XRESOLUTION, 204.0);
if (!stretch) {
float yres;
TIFFGetField(&faxTIFF, TIFFTAG_YRESOLUTION, &yres);
TIFFSetField(out, TIFFTAG_YRESOLUTION, yres);
} else
TIFFSetField(out, TIFFTAG_YRESOLUTION, 196.);
TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
TIFFSetField(out, TIFFTAG_PAGENUMBER, pn+1, npages);
rows = copyFaxFile(&faxTIFF, out);
fclose(in);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, rows);
if (verbose) {
fprintf(stderr, "%s:\n", argv[optind]);
fprintf(stderr, "%d rows in input\n", rows);
fprintf(stderr, "%d total bad rows\n", badfaxlines);
fprintf(stderr, "%d max consecutive bad rows\n", badfaxrun);
}
if (compression == COMPRESSION_CCITTFAX3 && isClassF) {
TIFFSetField(out, TIFFTAG_BADFAXLINES, badfaxlines);
TIFFSetField(out, TIFFTAG_CLEANFAXDATA, badfaxlines ?
CLEANFAXDATA_REGENERATED : CLEANFAXDATA_CLEAN);
TIFFSetField(out, TIFFTAG_CONSECUTIVEBADFAXLINES, badfaxrun);
}
TIFFWriteDirectory(out);
}
TIFFClose(out);
exit(0);
}
copyFaxFile(tifin, tifout)
TIFF *tifin, *tifout;
{
long row;
u_short badrun;
int ok;
tifin->tif_rawdatasize = TIFFGetFileSize(tifin->tif_fd);
tifin->tif_rawdata = malloc(tifin->tif_rawdatasize);
if (!ReadOK(tifin->tif_fd, tifin->tif_rawdata, tifin->tif_rawdatasize)) {
TIFFError(tifin->tif_name, "%s: Read error at scanline 0");
return (0);
}
tifin->tif_rawcp = tifin->tif_rawdata;
tifin->tif_rawcc = tifin->tif_rawdatasize;
(*tifin->tif_predecode)(tifin);
tifin->tif_row = 0;
badfaxlines = 0;
badfaxrun = 0;
bzero(refbuf, sizeof (refbuf));
row = 0;
badrun = 0; /* current run of bad lines */
while (tifin->tif_rawcc > 0) {
ok = (*tifin->tif_decoderow)(tifin, rowbuf, sizeof (rowbuf), 0);
if (!ok) {
badfaxlines++;
badrun++;
/* regenerate line from previous good line */
bcopy(refbuf, rowbuf, sizeof (rowbuf));
} else {
if (badrun > badfaxrun)
badfaxrun = badrun;
badrun = 0;
bcopy(rowbuf, refbuf, sizeof (rowbuf));
}
tifin->tif_row++;
if (TIFFWriteScanline(tifout, rowbuf, row, 0) < 0) {
fprintf(stderr, "%s: Write error at row %ld.\n",
tifout->tif_name, row);
break;
}
row++;
if (stretch) {
if (TIFFWriteScanline(tifout, rowbuf, row, 0) < 0) {
fprintf(stderr, "%s: Write error at row %ld.\n",
tifout->tif_name, row);
break;
}
row++;
}
}
if (badrun > badfaxrun)
badfaxrun = badrun;
free(tifin->tif_rawdata);
return (row);
}